﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace UnrealDebugger
{
    // Actions (Communication from UDK to IDE)

    partial class UnrealDebuggerIDE
	{
        private int _breakCount = 0;
        public int BreakCount
        {
          get { /*lock (_criticalSection)*/ { return _breakCount; } }
          set { /*lock (_criticalSection)*/ { _breakCount = value; } }
        }

        private int _lockedListCount = 0;
        public int LockedListCount
        {
            get { /*lock (_criticalSection)*/ { return _lockedListCount; } }
            set { /*lock (_criticalSection)*/ { _lockedListCount = value; } }
        }

        private object _criticalSection = new object();
        private Action _pendingAction = null;

        public void ExecuteAction(Action action)
        {
            /*lock (_criticalSection)*/
            {
                try
                {
                    _pendingAction = action;
                    if (this.IsHandleCreated && !this.IsDisposed)
                    {
                        this.Invoke(new MethodInvoker(delegate() { _pendingAction.SafeExecute(this); }));
                    }
                    _pendingAction = null;
                }
                catch (Exception /*e*/)
                {
                }
            }
        }

        public class Actions
        {
            public static void ShowDllForm()
            {
                UnrealDebuggerIDE ide = UnrealDebuggerIDE.Instance;
                ide.AttachDebugger();

                if (ide.IsWaitingForUDKResponse())
                {
                    switch (ide.ActiveCommand)
                    {
                        case "attach":
                        case "break":
                        case "stepover":
                        case "stepinto":
                        case "stepoutof": ide.UDKRespondedToActiveCommand(); break;
                    }

                    if (ide.BreakCount <= 0 && !ide.Project.BreakOnFirstLine)
                    {
                      Commands.Go();
                    }

                    ide.BreakCount++;
                }
            }

            public static void AddLineToLog(string line)
            {
                UnrealDebuggerIDE ide = UnrealDebuggerIDE.Instance;
                ide._outputPanel.AddLineToLog(line);
            }

            public static void CallstackClear()
            {
                UnrealDebuggerIDE ide = UnrealDebuggerIDE.Instance;

                ide._activeCallstackDepth = 0;
                ide._activeCallstackPosition = 0;
                ide._callstackPanel.Clear();
            }

            public static void CallstackEntry(string entry)
            {
                UnrealDebuggerIDE ide = UnrealDebuggerIDE.Instance;

                ide._activeCallstackDepth++;
                ide._callstackPanel.AddEntry(entry);
            }

            public static void ClearAWatch(int type)
            {
                UnrealDebuggerIDE ide = UnrealDebuggerIDE.Instance;

                switch (type)
                {
                    case 0: ide._localWatchPanel.ClearAWatch(); break;
                    case 1: ide._globalWatchPanel.ClearAWatch(); break;
                    case 2: ide._userWatchPanel.ClearAWatch(); break;
                }
            }

            public static void LockList(int list)
            {
                UnrealDebuggerIDE ide = UnrealDebuggerIDE.Instance;
                ide.LockedListCount++;

                switch (list)
                {
                    case 0: ide._localWatchPanel.LockList(); break;
                    case 1: ide._globalWatchPanel.LockList(); break;
                    case 2: ide._userWatchPanel.LockList(); break;
                }
            }

            public static void UnlockList(int list, UnlockListAction.WatchList buffer)
            {
                UnrealDebuggerIDE ide = UnrealDebuggerIDE.Instance;

                switch (list)
                {
                    case 0: ide._localWatchPanel.UnlockList(buffer); break;
                    case 1: ide._globalWatchPanel.UnlockList(buffer); break;
                    case 2: ide._userWatchPanel.UnlockList(buffer); break;
                }

                ide.LockedListCount--;

                if (ide.IsWaitingForUDKResponse())
                {
                    switch (ide.ActiveCommand)
                    {
                        case "changestack": if (ide.LockedListCount <= 0) { ide.UDKRespondedToActiveCommand(); }; break;
                    }
                }
            }

            public static void LoadClass(string className)
            {
                UnrealDebuggerIDE ide = UnrealDebuggerIDE.Instance;

                if (!ide.IsWaitingForUDKResponse())
                {
                    ide._activeCommand = "attach";
                }

                ide._activeDocument = ide.GetDocumentFromClassname(className);
                ide.ShowDocument(ide._activeDocument);
            }

            public static void GotoLine(int lineNo, int highlight)
            {
                UnrealDebuggerIDE ide = UnrealDebuggerIDE.Instance;

                if (ide._activeDocument != null)
                {
                    ide._activeLine = lineNo;
                    ide._activeDocument.GotoLine(lineNo, highlight);
                }
                else
                {
                    ide._activeLine = -1;
                }
            }

            public static Breakpoint ConnectBreakpoint(string className, int lineNo, bool connected)
            {
                UnrealDebuggerIDE ide = UnrealDebuggerIDE.Instance;

                return ide._project.ConnectBreakpoint(className, lineNo, connected);
            }

            public static Breakpoint EnableBreakpoint(string className, int lineNo, bool enabled)
            {
                UnrealDebuggerIDE ide = UnrealDebuggerIDE.Instance;

                return ide._project.EnableBreakpoint(className, lineNo, enabled);
            }
        }
	}
}
